<?php

defined('__VN_BASE') or define('__VN_BASE', dirname(__FILE__));

require_once 'vn.database.php';

class VNUser extends VNDatabase {

	private $VNUser;
	private $salt;

	public function __Construct($userName, $debug=false){

		try{

			//define user tables
			defined('TBL_USERS') or define('TBL_USERS', '`users`');
			defined('TBL_ROLES') or define('TBL_ROLES', '`roles`');

			//generate the salt based on the site name
			//prevents passwords from being exported to
			//other domains.
			$this->salt = substr(sha1($this->VNcore['__LPName']),0,6);

			//if any user data does not exist
			if(empty($userName)){

					//throw a user data exception
					throw new VNException("User Details Not Defined.",400,__CLASS__);

			}

			//construct the parent class
			parent::__Construct();


			if($_SESSION['uData']['uaccount'] != 'guest'){

				//fetch the user data from the database
				$uData = $this->fetchUserData($userName);

			}else{

				//set the guest data
				$uData = array(	'id'		=> '0',
						'username'	=> 'guest',
						'fName'		=> 'guest',
						'lName'		=> '',
						'ulevel'	=> '0');

			}
			//set the VNUser object credentials
			$this->VNUser = array("__uid" 	=> $uData['id'],
						"__uaccount"	=> $uData['username'],
						"__uname" 	=> $uData['fname'].' '.$uData['lname'],
						"__ulevel" 	=> $uData['ulevel']
			);


			if(empty($this->VNUser)){

				throw new VNException(__CLASS__,'User Details Not Defined',401);

			}

			//if debugging is turned on, print the VNUser details
			if($this->VNcore['__LPDebug'] == "user"){

				print "<pre id='debug'>".__CLASS__.":".__LINE__."<br/>";print_r($this->VNUser);print "</pre>";

			}

			//catch any exceptions thrown
		}catch(VNException $e){

			//print the exception and return false to stop any methods
			print $e;
			return false;

		}

	}
	public function __Destruct(){}

	public function account(){
		return $this->VNUser['__uaccount'];
	}

	public function name(){
		return $this->VNUser['__uname'];
	}

	public function permissions(){
		return $this->VNUser['__ulevel'];
	}

	public function uid(){
		return $this->VNUser['__uid'];
	}

	/*
	 * FUNCTION	-	fetchUserData
	 *
	 * @param username
	 *
	 * @return dataArray
	 *
	 */
	public function fetchUserData($username=false){
		try{
			/*
			 * TODO
			 *  - ulevel references `roles`.`id`
			 *  - business references `business`.`id`
			 */
			if($username){

				$q = sprintf("SELECT a.`id`, a.`ulevel`, a.`username`,a.`fname`,a.`lname`,a.`dob`,a.`gender`,a.`bid`,a.`phone`,a.`mobile`,a.`address`,a.`city`,a.`postcode`, b.`role`
								FROM ".TBL_USERS." a,".TBL_ROLES." b
								WHERE a.`username` = '%s' AND a.`ulevel` = b.`id`",
								mysql_real_escape_string($username));

			}else{

				$q = sprintf("SELECT a.`id`, a.`ulevel`, a.`username`,a.`fname`,a.`lname`,a.`dob`,a.`gender`,a.`phone`,a.`mobile`,a.`address`,a.`city`,a.`postcode`, b.`role`
								FROM ".TBL_USERS." a,".TBL_ROLES." b
								WHERE a.`ulevel` = b.`id`");

			}

			$r = $this->query($q) or die(print __CLASS__."[402] Error in query");

			if($r){

				if($username){

					return $this->fetchAssoc($r);

				}else{

					while($row = $this->fetchAssoc($r)){

						$arr[] = $row;

					}

					return $arr;
				}

			}

			throw new VNException("Could not fetch user data",403,__CLASS__);

		}catch (VNException $e){

			print $e;
			return false;

		}

	}

	public function createUser($uArr){

		try{

			foreach($uArr as $key => $value){

				if($key == 'password'){

					$value = sha1($this->salt.$value);

				}
				$qkey	.= "`".$key."`,";
				$qvalue .= "'".mysql_real_escape_string($value)."',";
			}

			$q = sprintf("INSERT INTO ".TBL_USERS." (%s) VALUES (%s)",
							mysql_real_escape_string(substr($qkey, 0, -1)),
							substr($qvalue, 0, -1)
							);

			$r = $this->query($q) or print "<strong id='error'>".__CLASS__." [404] Error in query<br/>".$q."</strong>";

			if($r){
				return true;
			}

			return false;

		}catch (VNException $e){

			print $e;
			//die();
		}

	}

	public function updateUser($uArr){

		try{

			foreach($uArr as $key => $value){

				if($key == 'password' || $key == 'secret'){

					$value = sha1($this->salt.$value);

				}

				$update	.= "`".mysql_real_escape_string($key)."` = '".mysql_real_escape_string($value)."',";

			}

			$q = sprintf("UPDATE ".TBL_USERS." SET ".substr($update, 0, -1)." WHERE `username` = '%s'",
							mysql_real_escape_string($uArr['username']));

			$r = $this->query($q) or print "<strong id='error'>".__CLASS__." [404] Error in query<br/>".$q."</strong>";

			if($r){
				return true;
			}

			return false;

		}catch (VNException $e){

			print $e;
			//die();
		}

	}

	public function userExists($username){

			$q = sprintf("SELECT `username` FROM ".TBL_USERS." WHERE `username` = '%s'",
							mysql_real_escape_string($username));

			$r = $this->query($q) or die(print __CLASS__." [405] Error in query");

			if($this->numRows($r) >= 1){

				return true;

			}

			return false;

	}

	public function checkCredentials($username,$password){

		$pass = sha1($this->salt.$password);

		$q = sprintf("SELECT `username`,`password`,`ulevel` FROM ".TBL_USERS." WHERE `username` = '%s' AND `password` = '%s'",
						mysql_real_escape_string($username),
						mysql_real_escape_string($pass));

		$r = $this->query($q);

		if($this->numRows($r) == 1){

			$row = $this->fetchAssoc($r);

			if($row){
				$_SESSION['uData']['uaccount'] = $row['username'];
				$_SESSION['uData']['ulevel'] = $row['ulevel'];
				return true;
			}

			return false;

		}

		return false;
	}

	/*
	* Password reset function, dont give them the chance to set a new one.
	*/
	public function forgotPassword($username,$email,$secret){

		try{

			if(empty($username) || empty($email) || empty($secret)){
				throw new VNException(__CLASS__,'Failed to reset password',490);
			}

			if(!$this->checkSecret($username,$email,$secret)){
				throw new VNException(__CLASS__,'User Details Not Defined',491);
			}

			// If all of the initial checks have been completed
			// and have all returned fine, generate the initial
			// hashed new password.
			$genHash = $this->genPassHash($username);

			// Check to see if the hash was completed successfully
			if(empty($genHash)){
				throw new VNException(__CLASS__,'User Details Not Defined',492);
			}

			// Generate the new salted password hash for the database
			$newpassword = sha1($this->salt.$genHash);

			$q = sprintf("UPDATE ".TBL_USERS."SET `password` = '%s' WHERE `username` = '%s' AND `email` = '%s'",
					mysql_real_escape_string($newpassword),
					mysql_real_escape_string($username),
					mysql_real_escape_string($email));

			$r = $this->query($q);

			if($r){

				print $genHash;

			}

			throw new VNException(__CLASS__,'User Details Not Defined',493);

		}catch( VNException $e ){
			print $e;
			return false;
		}
	}

	/*
	* Check the users secret
	*/
	private function checkSecret($username,$email,$secret){

		if(empty($username) || empty($email) || empty($secret)){
			return false;
		}

		$hashSecret = sha1($this->salt.$secret);

		$q = sprintf("SELECT * FROM ".TBL_USERS." WHERE `username` = '%s' AND `email` = '%s' AND `secret` = '%s'",
				mysql_real_escape_string($username),
				mysql_real_escape_string($email),
				mysql_real_escape_string($hashSecret));

		$r = $this->query($q);

		if($this->numRows($r) == 1){
			return true;
		}

		return false;
	}

	/*
	* Do some rediculous hashy stuff
	*/
	private function genPassHash($username){

		if(empty($username)){ return NULL; }

		$string = sha1(md5($username).$salt);
		$string = sha1(substr($string, 0, -7));

		if(strlen($string) >= 12){
			$string = substr($string, 0, 12);
		}

		return $string;
	}

/*
	public function printSecret($secret){

		print "<pre>";
		print "input : ".$secret;
		print "<br/>";
		print "output: ".sha1($this->salt.$secret);
		print "</pre>";

	}
*/
};

//emergency new password
//need to uncomment the printSecret() function.
//
//$user = new VNUser("admin");
//$user->printSecret("My Favorite Person");
//$user->forgotPassword("admin","my@email.com","My Favorite Person");
?>
